# -*- coding: utf-8 -*-
import scrapy
import re
from copy import deepcopy
# 因为异步的缘故，所以对于form_data需要用deepcopy深层复制，单独为数据开辟一个地址。

class BilianSpider(scrapy.Spider):
    name = 'bilian'
    allowed_domains = ['ebnew.com','ss.ebnew.com']

    keyword_s=['路由器','变压器']

    # 要发送的数据格式提前定义好,默认为空的字符串，多行内容复制过来之后，alt可以选中多行同时编辑
    sql_data=dict(
        projectcode='', #项目编号
        web='', #信息来源网站（例如：必联网）
        keyword='', #关键字
        detail_url='', #招标详细页网址
        title='', #第三方网站发布标题
        toptype='', #信息类型
        province='', # 归属省份
        product='', #产品范畴
        industry='', # 归属行业
        tendering_manner='', #招标方式
        publicity_date='', #招标公示日期
        expiry_date='', # 招标截止时间
    )

    # Form表单的数据格式
    form_data=dict(
        infoClassCodes='',
        rangeType='',
        projectType='bid',
        fundSourceCodes='',
        dateType='',
        startDateCode='',
        endDateCode='',
        normIndustry='',
        normIndustryName='',
        zone='',
        zoneName='',
        zoneText='',
        key='', # 搜索的关键字
        pubDateType='',
        pubDateBegin='',
        pubDateEnd='',
        sortMethod='timeDesc',
        orgName='',
        currentPage='', # 当前页码
    )


    def start_requests(self):
        # 通过start_requests发送的请求，可以跳过allowed_domains['ebnew']这个限定的host地址
        for keyword in self.keyword_s:
            form_data=deepcopy(self.form_data)
            form_data['key']=keyword
            form_data['currentPage']='1'
            request=scrapy.FormRequest(
                url='https://ss.ebnew.com/tradingSearch/index.htm',
                formdata=form_data,
                callback=self.parse_start,
            )
            # 把form_data保存到meta里面
            # request.META
            # 是一个Python字典，包含了所有本次HTTP请求的Header信息，比如用户IP地址和用户Agent（通常是浏览器的名称和版本号）。 注意，Header信息的完整列表取决于用户所发送的Header信息和服务器端设置的Header信息。 这个字典中几个常见的键值有：
            # HTTP_REFERER，进站前链接网页，如果有的话。 （请注意，它是REFERRER的笔误。）
            # HTTP_USER_AGENT，用户浏览器的user - agent字符串，如果有的话。 例如： "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17".
            # REMOTE_ADDR
            # 客户端IP，如："12.345.67.89" 。(如果申请是经过代理服务器的话，那么它可能是以逗号分割的多个IP地址，如："12.345.67.89,23.456.78.90" 。)
            # ……
            request.meta['form_data']=form_data
            yield request
        # yield scrapy.Request(
        #     url='https://www.ebnew.com/businessShow/646488801.html',
        #     callback=self.parse_page2,
        # )
        # form_data=self.form_data
        # form_data['key']='路由器'
        # form_data['currentPage']='2'
        # yield scrapy.FormRequest(
        #     url='https://ss.ebnew.com/tradingSearch/index.htm',
        #     formdata=form_data,
        #     callback=self.parse_page1,
        # )

    # 定义一个循环体，通过访问第一页拿到所有页码数，对总页码数进行循环，发送每一页的url请求。
    def parse_start(self,response):
        # form_data=response.meta['form_data']
        a_text_s=response.xpath('//form[@id="pagerSubmitForm"]/a/text()').extract()
        page_max=max(
            # 通过re.match对比，如果内容都是数字，则对内容转换int类型
            [int(a_text) for a_text in a_text_s if re.match('\d+',a_text)]
        )
        # page_max=2
        # 启用redis，注释掉页码，采用max
        self.parse_page1(response)
        # 此处从第二页访问的原因是，parse_start访问的就是第一页。
        for page in range(2,page_max+1):
            form_data=deepcopy(response.meta['form_data'])
            form_data['currentPage']=str(page)
            request=scrapy.FormRequest(
                url='https://ss.ebnew.com/tradingSearch/index.htm',
                formdata=form_data,
                callback=self.parse_page1
            )
            # 把请求交给调度器
            request.meta['form_data']=form_data
            yield request




    # 把response响应回来的页面保存到本地
    # 一级页面
    def parse_page1(self,response):
        # 获取到form_data，为后面的keywords的获取作准备
        form_data=response.meta['form_data']
        keyword = form_data.get('key')
        content_list_x_s=response.xpath('//div[@class="ebnew-content-list"]/div')
        for content_list_x in content_list_x_s:
            sql_data=deepcopy(self.sql_data)
            # 标的状态，
            sql_data['toptype']=content_list_x.xpath('./div[1]/i[1]/text()').extract_first()
            sql_data['title']=content_list_x.xpath('./div[1]/a[1]/text()').extract_first()
            sql_data['publicity_date']=content_list_x.xpath('./div[1]/i[2]/text()').extract_first()
            if sql_data['publicity_date']:
                sql_data['publicity_date']=re.sub('[^0-9\-]','',sql_data['publicity_date'])
            sql_data['tendering_manner']=content_list_x.xpath('./div[2]/div[1]/p[1]/span[2]/text()').extract_first()
            sql_data['product']=content_list_x.xpath('./div[2]/div[1]/p[2]/span[2]/text()').extract_first()
            sql_data['expiry_date']=content_list_x.xpath('./div[2]/div[2]/p[1]/span[2]/text()').extract_first()
            sql_data['province']=content_list_x.xpath('./div[2]/div[2]/p[2]/span[2]/text()').extract_first()
            sql_data['detail_url'] = content_list_x.xpath('./div/a/@href').extract_first()
            sql_data['keyword']=keyword
            sql_data['web']='必联网'

            request=scrapy.Request(
                url=sql_data['detail_url'],
                callback=self.parse_page2,
            )
            request.meta['sql_data']=sql_data
            yield request

    # 二级页面
    def parse_page2(self,response):
        sql_data=response.meta['sql_data']
        li_x_s=response.xpath('//ul[contains(@class,"ebnew-project-information")]/li')
        sql_data['projectcode'] = response.xpath('//ul[contains(@class,"ebnew-project-information")]/li[1]/span[2]/text()').extract_first()


        if not sql_data['projectcode']:
            # body=response.xpath('//div[@class="ebnew-details-content mg-t30"]//div[contains(@class,"detials-content")]').extract()[0]
            # body=re.sub('^<.*?$>','',body)
            # body=re.sub('\n','',body)
            # 上面注释掉的内容可能不行。所以开始考虑匹配body下的text()内容
            body1 = response.xpath('//body//text()').extract()
            body1 = ''.join(body1)
            # body1 = re.sub('\n', '', body1).replace(' ', '').strip()
            body1 = re.sub('\s', '', body1)
            # print(len(body1))
            # print(body1)
            # print(type(body1))

            # 有可能在二级页面下内容中出现编号，有匹配到“项目编号加上0-1个冒号,空格出现0-2次,项目编号可能是大小写字母以及数字- _”
            projectcode_find=re.findall('编号[:：]{0,1}\s{0,2}([a-zA-Z0-9\-_]{10,80})',body1)
            # print(projectcode_find)
            sql_data['projectcode']=projectcode_find[0] if projectcode_find else ""
            # 结果甲 if 条件甲 else 结果乙 if 条件乙 else 结果丙
        # elif not projectcode:
        #     # 有可能在二级页面下内容中的表格出现编号，https://www.ebnew.com/businessShow/646488801.html
        #     # projectcode=li_x_s[0].xpath('//table[@class="min_tablehz"]//text()').extract_first().strip()
        #     projectcode_find=re.findall('工程项目编号[: :]{0,1}([a-zA-Z0-9\-_]){10,80}',response.body.decode('utf-8'))
        #     projectcode=projectcode_find[0]
        # else:
        #     projectcode=""
        sql_data['industry'] = response.xpath('//ul[contains(@class,"ebnew-project-information")]/li[8]/span[2]/text()').extract_first()
        # print('parse_2',sql_data)
        yield sql_data